home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Code Resources / Jims CDEFs 1.50 / Documents / About CDEFs < prev    next >
Encoding:
Text File  |  1995-10-30  |  55.9 KB  |  1,385 lines  |  [TEXT/KAHL]

  1. Jim's CDEFs  - Copyright © 1994-1995 by James G. Stout
  2. --------------------------------------------------------------------------------
  3. About Jims CDEFs…
  4.  
  5. If you have downloaded previous versions of this package, please read the 
  6. "Version history" file, some minor but important details have changed !!
  7.  
  8. Also, please read the license agreement in the "Conditions for use…"
  9. document included with the package.
  10.  
  11. This is a collection of 11 CDEFs (Control Definitions) some bits of
  12. source code to demo their use AND the source code for all of the CDEFs.
  13.  
  14. (If you are new to Mac programming, CDEFs are code resources that can just
  15. be pasted into your project's resource file and used by your programs).
  16.  
  17. Jim Stout
  18.  
  19. June 1995
  20.  
  21. I can be reached electronically at:
  22.  
  23. Internet    : JimS@WRQ.COM    (work hours, PST)
  24. AppleLink   : WRQ            (daily)
  25. CompuServe  : 73240,2052    (weekly or so)
  26. AOL         : JasG            (weekly or so)
  27. eWorld      : Jim Stout        (weekly or so)
  28. --------------------------------------------------------------------------------
  29.  
  30. The CDEFs or other code in this package may be incorporated in any freeware, 
  31. shareware, commercial or other software package, subject to the conditions in
  32. the "License for Use" that accompanies this package.
  33.  
  34. --------------------------------------------------------------------------------
  35.  
  36. The CDEFs in this package are:
  37.  
  38. procID    Name            Function
  39. ------    -----------        --------------------------------------------------------
  40. 0        3D√ Buttons        as 1107, but with a "real" check mark for checkBoxes
  41. 1100    GroupBox        Titled box, text in upperleft
  42. 1101    PopUp Menu        System 7 style popup menu control for System 6 or 7
  43. 1102    Spinner            A "little arrows" control
  44. 1103    Date & Time        Date & Time control using "little arrows"
  45. 1104    Tog Button        New type of "one or many" control
  46. 1105    HSlider            Horizontal slider control
  47. 1106    VSlider            Vertical slider control
  48. 1107    3D Buttons        3d replacement for the standard button CDEF
  49. 1108    Progress Bar    A "thermometer" or "barber pole" progress indicator
  50. 1109    TabPanel        A "Tab Panel" control as in MSWord
  51. 1110    Slider            A vert or horiz slider.
  52. 1111    3D Buttons-rect    A rectangular version of the 3D Buttons CDEF
  53.  
  54. --------------------------------------------------------------------------------
  55.  
  56. The source code for all of the CDEFs is included in the "CDEF Source" folder.
  57. Also included are Think, Symantec, CodeWarrior projects and MPW makefiles
  58. required to build the CDEFs.
  59.  
  60. A set of standard #defines for variation codes etc. is provided in file
  61. "jimsCDEF.h".
  62.  
  63. Also included is source for utility routines common to all of the CDEFs.  
  64. A test harness to allow source level debugging is also included.  Rather
  65. than take up the room for 11 test projects and code, there is only one - for
  66. the 3D Button CDEF.  Test projects for the other 10 is left to the reader as
  67. a programming exercise.
  68.  
  69. --------------------------------------------------------------------------------
  70. This file is getting pretty long, it is divided into the following sections:
  71.  
  72.     - Introduction
  73.     - Control Descriptions
  74.     
  75. CDEF details
  76.     - Variation codes & control size 
  77.     - Non-standard control RefCon usage
  78.     - Non-standard control template usage
  79.     
  80. General information
  81.     - Using custom controls in a dialog
  82.     - Using custom controls in a window
  83.     - Colorizing Controls & Dialogs
  84.     - Changing the font in a Dialog
  85.     
  86.     - Special popup menu notes
  87.     - About "TogButtons" 
  88.     - About Tab Panels
  89.     - Revision history
  90.  
  91. --------------------------------------------------------------------------------
  92. Introduction
  93. ============
  94.  
  95. In early 1994, I was reading the Human Interface volume of Inside Mac and it
  96. struck me as funny that Apple refers to various controls (used throughout the
  97. MacOS) as "not supported by the Toolbox".  Controls like "little arrow"
  98. controls used to set Date & Time, Memory etc., "Slider  Controls" like those in
  99. the Sound or Brightness control panels and a "Progress Bar" are simply are not
  100. to be found in the Toolbox.
  101.  
  102. Apple simulates controls by displaying appropriate PICT's and handling mouse
  103. events in a dialog filter (I think).
  104.  
  105. I realized that over the past couple of years, I had written some of those
  106. controls (the rest are hot off my coding pad).
  107.  
  108. Two of the CDEFs, 1104 "Tog Button" and 1109 "TabPanel" are a little different. 
  109. This is explained below in the sections "About Tog Buttons" and "About Tab 
  110. Panels.
  111.  
  112. All of these controls will work with System 6 or System 7 - the only caveats
  113. are:
  114.  
  115.     - PopUpMenu control requires PopUpMenuSelect.  
  116.     - TabPanel control requires AppendDITL etc. (System 6 with CTB or System 7)
  117.     - 32bit ColorQuickdraw v1.2 is required for any of the controls to draw
  118.       "3D" variants and to use the System 7 style gray when disabled.
  119.           
  120. I have tested them on machines from a MacPlus through a Power Mac 8100.
  121. (Actually, I've tested these as far back as System 3.2 - I've gotta do
  122. something with that original 128k Mac with MacPlus ROM's that  is sitting in
  123. the corner...)
  124.  
  125. All controls with titles honor the "useWindFont" variation code (to draw in a
  126. non-System font) and if possible, the controls will honor control colors found
  127. in 'cctb' resources.
  128.  
  129. The "3D Buttons" and "TabPanel" CDEFs will always use a "3D" effect if the
  130. background color is non-white AND the control can draw itself in color. 
  131. This behavior cannot be overridden for these controls.  Sorry.
  132.  
  133. As far as I can tell, the controls all handle low memory situations by 
  134. refusing to draw themselves.  Let me know if you see any problems.
  135.  
  136. I have not written these to support non-roman script systems.
  137.  
  138. Other variation codes, sizes and non-standard control template values are
  139. listed below.
  140.  
  141. --------------------------------------------------------------------------------
  142. Control Descriptions
  143. ====================
  144.  
  145. Common features:
  146.  
  147.     - color per 'cctb' resources.
  148.     - disable with "GrayishTextOr" effect under System 7.
  149.     - have an embossed, 3D variation.
  150.     - respect the "useWindFont" variation code (8).
  151.     - All control drawing is clipped to the control rect, so it should be
  152.       pretty obvious if you have a control rect that is too small.
  153.     
  154.     NOTE: all of these controls rely on a private data structure stored in
  155.           the contrlData field of the control structure.  Don't
  156.           use this field for your own use or unpredictable things
  157.           will happen.
  158.           
  159.           Also, some of the controls look at the value of the refCon when
  160.           initializing to get some extra parameters.
  161.           
  162.           If you want to place a value in the refCon for your program's use, 
  163.           don't set it until AFTER you call NewControl or NewDialog and
  164.           the controls have been initialized. (The DateTime CDEF is a MAJOR
  165.           exception - see below - it uses the refCon for its "value" field.)
  166.             
  167. --------------------------------------------------------------------------------
  168. GroupBox
  169.  
  170.     This control is pretty simple. It frames the control rect and places
  171.     the title in the upper left corner.
  172.     
  173.     It can be used to logically group a series of related controls.
  174.     
  175.     It does not respond to mouse clicks, it does have variation
  176.     codes for a dashed-line frame and a 3D effect.
  177.     
  178.     To use this control, you have to play some games with the control
  179.     rect to keep it from overlaying other controls.  Essentially, you
  180.     must set the control rect height to include ONLY the title and then
  181.     specify the true height of the control in the contrlMax field.
  182.     
  183.     In response to an update event, you will need to call DrawControls or 
  184.     Draw1Control for this control. 
  185.     
  186.     UpdtControls WILL NOT WORK !!!!
  187.     
  188. --------------------------------------------------------------------------------
  189. PopUp Menu
  190.  
  191.     This control was written to replace both the System 6 & 7 versions of
  192.     the Apple CDEF 63.  
  193.     
  194.     Apple's CDEF has some problems - it behaves  differently under System 6 
  195.     and System 7.  The System 6 version does not honor menus with icons,
  196.     requires a special variation code for color menus and has problems with
  197.     menus narrower than the control rect (when using the popupFixedWidth
  198.     variation code).  
  199.     
  200.     The System 7 version does not draw colored menus at all.
  201.     
  202.     Neither version will work with a dynamically created menu.
  203.  
  204.     You should be able to use this CDEF with the same parameters as the
  205.     Apple CDEF.
  206.     
  207.     There are several enhancements explained in the section on Non-standard
  208.     control template usage and in the "Special popup menu notes" section.
  209.     
  210.     The handle stored in the contrlData field is as documented by Apple
  211.     and can be used to retrieve the MenuHandle of the popup menu.  See
  212.     IM VI and the jimsCDEF.h file.
  213.     
  214. --------------------------------------------------------------------------------
  215. Spinner
  216.  
  217.     This a control that "Apple never wrote".  It allows for adjustment of
  218.     a numeric value via "little" arrows.  The arrows can be vertical or
  219.     horizontal.
  220.     
  221.     The default increment is 1, but this can be specified in the control
  222.     template in the refCon field.  The control value will increment in
  223.     a "ballistic" manner - as the mouse button is held down, the increment
  224.     value will increase from 1 to 10 to 100 to 1000.
  225.     
  226.     This CDEF can be "linked" to a dialog edit text item to update.
  227.     
  228.     CDEFs cannot get keyDown events, so the trick here is to have the
  229.     CDEF update the edit text item.  To do this, set the HiWord of
  230.     control refCon to a DITL editText item number to be updated.  In
  231.     this case, set the LoWord of the refCon to the desired increment.
  232.     
  233.     The calling program must take care of insuring that only digits
  234.     are typed into the edit text. ALSO, when the user types new
  235.     digits, the calling program must get the contents of the edit item,
  236.     convert it to a number and call SetCtlValue to let the control
  237.     know about the new value.  Otherwise, the next click in the 
  238.     control will wipe out the typed value.
  239.     
  240.     The handle stored in the contrlData field is documented in the
  241.     jimsCDEF.h file.  There is a "userData" field for your use.
  242.     
  243.     PartCodes returned via TrackControl are :
  244.         2 - in up arrow
  245.         3 - in down arrow
  246.         
  247.     (the control will have updated its value when TrackControl returns)
  248.     
  249. --------------------------------------------------------------------------------
  250. Date & Time
  251.  
  252.     This is a control to adjust Date and/or Time values.  Clicking on
  253.     a time or date component (month, hours, etc.) will highlight 
  254.     those digits and show "little" arrows that can be used to adjust 
  255.     the date or time value.
  256.     
  257.     Variation codes can specify display of Date, Time, both, horizontal 
  258.     or vertical display.  The m/d/y order of the date will match what 
  259.     the user has set in the Date & Time control panel.  Leading zeros
  260.     are always drawn - it makes things a lot simpler for the CDEF.
  261.     
  262.     Likewise, 12 or 24 hour time is taken from the system settings. To
  263.     force a 24 hour setting, pass a non-zero contrlMax in the control 
  264.     template. To get a "3D" effect for the control title and arrows, 
  265.     pass a non-zero contrlMin in the control template.
  266.     
  267.     The "value" of the control is a DateTimeRec.  Since this is a long,
  268.     it is stored in the contrlRfCon field, NOT in the contrlValue field
  269.     of the control record. So, rather than using GetCtlValue(), use
  270.     GetCRefCon() to access the control value.
  271.     
  272.     There is no keyboard handling for setting date & time.  CDEFs do
  273.     not have any mechanism for keyboard events.  I think that this could
  274.     be done from a user program, but I'll leave that as an exercise for
  275.     those that need it. 
  276.     
  277.     (Hint, the contrlValue is always the highlighted digits field and you can 
  278.     change the date & time shown by the control    by setting a new DateTimeRec 
  279.     into the control RefCon and drawing the    control.)
  280.     
  281.     Resetting the date and time requires the following:
  282.     
  283.                 GetDateTime(&secs);
  284.                 SetCRefCon(hCtrl, secs);
  285.                 InvalRect(&(**hCtrl).contrlRect);
  286.     
  287. --------------------------------------------------------------------------------
  288. Tog Button
  289.  
  290.     This is explained in great detail below.
  291.     
  292.     A "Tog" button is a diamond shaped control, a mix of CheckBox and
  293.     Radio button behavior.  A group of these controls can have many
  294.     "on" members (like a checkbox), but must always have one member
  295.     that is "on" (like a radio button).
  296.     
  297.     This file requires use of some support routines in TogLib.c that
  298.     must be called by your program.
  299.     
  300.     Variation code 4 in the 3D Buttons control will have the same
  301.     result.
  302.     
  303. --------------------------------------------------------------------------------
  304. HSlider
  305.  
  306.     This is an exact duplicate of the slider control in the Brightness
  307.     Control Panel.
  308.     
  309.     Several variation codes are available to alter the appearance of
  310.     the control.  See below or the demo program.
  311.     
  312.     This and the VSlider control will call back to an "actionProc" if
  313.     one is set via SetCtlAction() and you call TrackControl with -1 as
  314.     the last parameter.  This could be used to implement a "live" 
  315.     display of the control value as the thumb is dragged around.
  316.     
  317.     Part codes returned to TrackControl are :
  318.         1 - in "thumb"
  319.         2 - in "decrease"
  320.         3 - in "increase"
  321.  
  322.     The control is drawn using internal bitmap data and cannot be easily
  323.     customized.
  324. --------------------------------------------------------------------------------
  325. VSlider
  326.  
  327.     This is an exact duplicate of the slider control in the Sound
  328.     Control Panel.
  329.  
  330.     Several variation codes are available to alter the appearance and
  331.     behavior of the control.  See below or the demo program.
  332.     
  333.     See notes above for "actionProc" & TrackControl issues.
  334.     
  335.     The control is drawn using internal bitmap data and cannot be easily
  336.     customized.
  337. --------------------------------------------------------------------------------
  338. Slider
  339.  
  340.     This is yet another variation on a slider control.  It will orient itself
  341.     vertically or horizontally based on the control rect.
  342.     
  343.     This slider does not use internal bitmaps for its drawing, so you can
  344.     easily modify its appearance by making changes to the drawing routine.
  345.     
  346.     See notes above for "actionProc" & TrackControl issues.
  347.     
  348. --------------------------------------------------------------------------------
  349. 3D Buttons
  350.     
  351.     This provides 3D equivalent to the standard push button, radio button and
  352.     check box controls.
  353.     
  354.     An addition is variation code 4 - in this control it forces the push
  355.     button to be the same color as as the window background, ignoring any
  356.     'cctb' resources.
  357.     
  358.     #defines in file cdef3D.c allow you to create a square edged version, a
  359.     version that is always gray or a version with a "real checkbox".
  360.     
  361. --------------------------------------------------------------------------------
  362. Progress Bar
  363.  
  364.     This is a control to provide a "thermometer" or "barber pole"
  365.     indicator. It can be used to display the progress of a long 
  366.     running operation (like the thermometer in the "Copying file…" 
  367.     alert.  The "barber pole" variation can be used when the
  368.     operation is proceeding, but the end point is not known - like
  369.     searching for a series of files.
  370.     
  371.     Variation codes can be used for horizontal, vertical, rectangular,
  372.     oval or barber pole indicators.
  373.     
  374. --------------------------------------------------------------------------------
  375. TabPanel
  376.     
  377.     This too, is explained in great detail below.
  378.     
  379.     This is a problematic control.  It will be too "Windows-like" for
  380.     many.  I wrote it to see if it could be done on the Mac after seeing
  381.     what a co-worker was doing.  Don't use it if you don't like it.
  382.     
  383.     It draws a box with a series of "tabs" long the top edge, like At Ease
  384.     in some respects.  It could be used to provide a dialog with multiple
  385.     "panels" - like the Think Project Manager "Options" dialog which uses
  386.     a popup to switch panels, or many CommToolbox tools which use a list
  387.     of icons. 
  388.     
  389.     By default, there are 4 tabs per row with a maximum of 5 rows of tabs.
  390.     This can be changed to get between 2 and 8 tabs/row.
  391.     
  392.     Clicking on a "tab" will change the control value. Your program can
  393.     then change the other controls on the panel - either by hiding/showing
  394.     controls or using ShortenDITL/AppendDITL calls.
  395.         
  396.     To use this control, you have to play some games with the control
  397.     rect to keep it from overlaying other controls.  Essentially, you
  398.     must set the control rect height to include ONLY the tab titles and
  399.     then specify the true height of the control in the contrlMin field.
  400.  
  401.     In response to an update event, you will need to call DrawControls or 
  402.     Draw1Control for this control. 
  403.     
  404.     UpdtControls WILL NOT WORK !!!!
  405. --------------------------------------------------------------------------------
  406. CDEF details
  407. --------------------------------------------------------------------------------
  408.  
  409. See file jimsCDEF.h for #defines for variation codes and structs for private
  410. data for Spinner & Popup menu CDEFs.
  411.  
  412. Variation codes & control size 
  413. ==============================    
  414.  
  415. (min h & w is minimum required height & width for the control rect 
  416. when using Chicago 12 font)
  417.  
  418. CDEF        varCode        min h & w    Result
  419. ---------    ----------    ----------    --------------------------------------------
  420. GroupBox    0            16 x nn        Draws a solid frame
  421.             1                        Draws a dotted frame
  422.             2                        3D effect on non-white backgrounds
  423.             4                        an "inset box" effect on non-white backgrounds
  424.             8                        Use the Window font for title
  425.             
  426.             NOTE: To avoid problems with "layering" of this control over or
  427.                   under the contents of a box, set the height of this control 
  428.                   to 16 or so, then put the height you REALLY want in the 
  429.                   contrlMax field of the CNTL template.  The control rect 
  430.                   (used by the Dialog Manager) will not obstruct other controls.
  431.                   However, when the control draws - it will use the height value
  432.                   from the contrlMax field.
  433.                   
  434.                   Uses cFrameColor & cTextColor from 'cctb'
  435.                   
  436. --------------------------------------------------------------------------------            
  437. PopUp Menu                19 x nn        (see IM VI or Docs for Apple CDEF 63
  438.                         19 x 25        for "triangle only" menu
  439.             1                        use fixed width for menu
  440.             2                        3D effect
  441.             4                        use refCon for AddResMenu
  442.             8                        Use the Window font for title & menu
  443.             
  444.             NOTE: if the menu has styled text items, the height may need to be 
  445.                   greater than 19.  It will need to be enlarged to if you have
  446.                   icons on the menu - make the height equal icon height + 5.
  447.                   
  448.                   Unlike the Apple CDEF 63, this control will:
  449.                     - behave the same with System 6 & 7
  450.                     - properly handle colored menus
  451.                     
  452.                   There are several enhancements, see below.
  453.                     
  454.                   Uses cTextColor for title and colors from 'mctb' for menu.
  455.                   
  456. --------------------------------------------------------------------------------    
  457.  
  458. Spinner        0            20 x nn        Small, as in "Date & Time" Control panel
  459.             1            27 x nn        Large, as in "Memory" Control panel
  460.             2                        3D arrows
  461.             4                        Horizontal arrows
  462.             8                        Use the Window font for drawing
  463.             
  464.             NOTE: use 20 x 13 or 27 x 17 to get arrows only.
  465.                   3D arrows are colored, as are system scroll bars, with
  466.                   with cTingeLight & cTingeDark.
  467.                   
  468. --------------------------------------------------------------------------------    
  469.  
  470. Date & Time    0            20 x 160    Date left, Time right justified    
  471.             1            20 x 80        Date only, left justified    
  472.             2            20 x 80        Time only, left justified    
  473.             4            37 x 80        Both on 2 lines, date over time
  474.             8                        Use the Window font for drawing
  475.                         
  476.             NOTE: non-standard date or time separator characters may   
  477.                   need a larger rect.  Also, if a title is specified,
  478.                   the width of the control will need to be increased.
  479.                   
  480.                   Uses cFrameColor & cTextColor.  3D arrows colored
  481.                   with cTingeLight & cTingeDark.
  482.                   
  483. --------------------------------------------------------------------------------    
  484.                                 
  485. Tog Button    0            18 x nn        Normal button title
  486.             1                        * not used *
  487.             2                        * not used *
  488.             4                        * not used *
  489.             8                        Use the Window font for title
  490.             
  491.                   Uses cFrameColor & cTextColor from 'cctb'
  492.                   
  493. --------------------------------------------------------------------------------    
  494.                         
  495. HSlider        0            24 x 121    As in the "Brightness" Control panel
  496.             1                        Scale drawn in white (not filled)
  497.             2                        Drawn with a 3D effect
  498.             4                        Scale drawn in gray pattern
  499.             8                        * not used *
  500.             
  501.             Uses cFrameColor, cBodyColor, cThumbColor & cTextColor from 'cctb'
  502.                   
  503. --------------------------------------------------------------------------------    
  504.  
  505. VSlider        0            105 x 42    As in the "Sound" Control panel
  506.             1                        Scale drawn in white (not filled)
  507.             2                        Drawn with a 3D effect
  508.             4                        "Thumb" will not "snap" to tick mark
  509.             8                        Scale is blank, no numbers, no marks
  510.             
  511.             NOTE: ht is 12*divisions + 21 (see below)
  512.             
  513.             Uses cFrameColor, cBodyColor, cThumbColor & cTextColor from 'cctb'
  514.             
  515. --------------------------------------------------------------------------------    
  516.  
  517. Slider        0            any x any    "Thumb" is always equal to smallest dimension
  518.             1                        Scale inset 4 pixels from thumb (control rect)
  519.             2                        Scale inset 8 pixels
  520.             4                        scale filled with cTingeDark
  521.             8                        click on scale moves thumb to that point    
  522.               
  523. --------------------------------------------------------------------------------    
  524.  
  525. 3D Buttons    0            any x any    draws a push button
  526.             1                        draws a checkbox
  527.             2                        draws a radiobutton
  528.             4                        draws a Tog Button control
  529.             8                        Use the Window font for title
  530.             
  531.             NOTE: This control should behave just like the standard CDEF 0 when 
  532.                     running in 1 bit (B&W) mode OR if the background is white. If 
  533.                     running on a non-white background, this CDEF will draw "3 D" 
  534.                     controls.
  535.                     
  536.                   Uses cFrameColor & cTextColor from 'cctb'. Gray shading is a
  537.                   gray that is intermediate to the background color & cFrameColor.
  538.                   
  539. --------------------------------------------------------------------------------    
  540.  
  541. Progress Bar 0            any x any    draws a horizontal progress bar
  542.              1                        draws a vertical progress bar
  543.              2                        draws a rounded, 3D progress bar
  544.              4                        draws a "Barber Pole" progress bar
  545.              8                        not used
  546.              
  547.             NOTE: to get a "Barber Pole" variation to work, you need to call
  548.                     it with a different value each time.  Simply setting min=0
  549.                     and max=1, then setting its value to 0, then 1, then 0 etc.
  550.                     inside your loop operation will work.
  551.           
  552.                     'cctb' resource entries for cFillPat and cTingeLight are used
  553.                     to color this control.
  554.                     
  555. --------------------------------------------------------------------------------
  556.  
  557. TabPanel     0            20 x nn        tab label is Geneva 9, bold for active tab.
  558.              1                        Use System font for tab label, underline
  559.                                      for active tab.
  560.              2                        1 row of tabs, contrlMax columns.
  561.              4                        not used
  562.              8                        Use the Window font for tab label, bold
  563.                                      for active tab.
  564.     
  565.             NOTE: To avoid problems with "layering" of this control over or
  566.                   under the contents of a box, set the height of this control to
  567.                   16 * rows, then put the height you REALLY want in the contrlMin 
  568.                   field of the CNTL template.  The control rect (used by the 
  569.                   Dialog Manager) will not obstruct other controls.  However, 
  570.                   when the control draws - it will use the height value from the 
  571.                   contrlMin field.
  572.                   
  573.                   Uses cFrameColor & cTextColor from 'cctb'. Gray shading is a
  574.                   gray that is intermediate to the background color & cFrameColor.
  575.  
  576.                   The default of 4 tabs per row can be changed via the LoWord of
  577.                   the refCon to 2 - 8.  See below.
  578. --------------------------------------------------------------------------------    
  579.             
  580. Non-standard control refCon usage
  581. ===================================
  582.  
  583. Note:     Several of these controls use the control refCon field.  Strictly
  584.         speaking, the refCon should be left for the caller's use, not for
  585.         the CDEF.  But… the Apple CDEF broke the rule and I blithely 
  586.         followed along (sorry).  Except for the DatTime CDEF, the refCon is
  587.         used only at the time the CDEF intializes, and its value is used
  588.         to produce non-default behavior or appearance.  
  589.         
  590.         If you need the refCon change the appropriate init() routine for 
  591.         the CDEF.
  592.         
  593. PopUp Menu     - use of refCon is identical to Apple's CDEF 63
  594.  
  595.             - not used by control after initialization.
  596.                     
  597. Spinner        - refCon may be used to indicate an "increment" value.  Also,
  598.               you can set both an increment and a DITL item (for an edit
  599.               text item to update). See below.
  600.             - the increment value is limited to 1-1000 and the DITL item
  601.               number must be 0-100.
  602.               
  603.             - not used by control after initialization.
  604.                     
  605. VSlider     - refCon may be used to indicate the number of divisions 
  606.               but will default to 7 divisions.  Must be in the range
  607.               2-20.
  608.               
  609.             - not used by control after initialization.
  610.                     
  611. DateTime    - refCon is the "value" of the control.  It is updated
  612.               by the control.
  613.               
  614.             - ** USED ** by control after initialization - see below.
  615.                 
  616. Tab Panel    - LoWord of the refCon is "tabs per row" - from 2 to 8. If
  617.               outside this range, the default is 4 tabs per row.
  618.             - HiWord of the refCon is a "notch".  If non-zero, there will
  619.               be a notch in the the right corner with no tab, if zero,
  620.               tabs will fill the entire width of the control.  This value
  621.               must be between 0 and control width/2.
  622.               
  623.             - not used by control after initialization.
  624.                     
  625. --------------------------------------------------------------------------------
  626.  
  627. Non-standard control template usage
  628. ===================================
  629.  
  630. The Macintosh Control Manager is pretty limited in its capability for numerous
  631. control variants (just look at the popup menu CDEF!), allowing overlapping
  632. controls or passing special data to the control.
  633.  
  634. I attempted to make it possible to initialize all of these controls via standard
  635. 'CNTL' templates or calls to NewControl() rather than requiring the calling 
  636. program to make additional calls or use special data structures.  This approach
  637. means the the meanings of some template values have been redefined as listed
  638. below:
  639.  
  640. GroupBox        does not use min, value or refCon. max is used for the
  641.                 true height of the control.
  642.                 
  643.                 Rect should be 16 pixels high, just enough for the title.
  644.  
  645. PopUp Menu        (see Inside Mac VI or other Docs for Apple CDEF 63)
  646.                 
  647.                 Briefly:
  648.  
  649.                 procId    : 1616 + varCode  (1101 * 16) + varCode
  650.                         : varCodes
  651.                             popupFixedWidth        = 0x0001
  652.                             ctl3D                = 0x0002
  653.                             popupUseAddResMenu    = 0x0004
  654.                             popupUseWFont        = 0x0008
  655.                             
  656.                 value    : Title justification
  657.                            :     popupTitleLeftJust        = 0x00000000
  658.                          :     popupTitleCenterJust    = 0x00000001
  659.                          :     popupTitleRightJust        = 0x000000FF
  660.                          
  661.                            There are also several values for setting text
  662.                            style for the popup title.  See Inside Mac.
  663.  
  664.                 min        : resId of menu to use, even if using 
  665.                           popupUseAddResMenu, it is best to have a 
  666.                           'dummy' menu resource with no items defined.
  667.  
  668.                 max        : width of title item - from controlRect.left  
  669.                         :  0 = no title drawn.
  670.                         
  671.                         Enhancements:
  672.                         
  673.                         The following are 8 "pseudo variation codes" that can
  674.                         be added to the max field (title width).
  675.                     
  676.                           popupNoMark          : Don't use a checkmark on current item.
  677.                           
  678.                           popupBlackSymbol    : Always draw symbol in black.
  679.                           
  680.                           popupInsetFrame     : Draws an inset 3D popup frame.
  681.                           
  682.                           popupSymbolOnly     : Draw popup symbol for "type-in menus"
  683.                           
  684.                           popupNoSymbol          : Don't draw popup symbol at all.
  685.                           
  686.                           popupCenterText     : Don't draw popup symbol, don't expand 
  687.                                                 control width to that of the menu and
  688.                                                 center item text in control rect.
  689.                                                 
  690.                           popupIconOnly          : Draw item Icon in a framed box.
  691.                           
  692.                           popupNoDeleteMenu : Don't call DeleteMenu until control is
  693.                                                 disposed of. This will preserve menu color
  694.                                               information created via calls to SetMCEntries 
  695.                                               (as opposed to those in 'mctb' resources).
  696.                           
  697.                         : use of these means that the title width must be less
  698.                           than 255 characters, but that seems to be a rather
  699.                           reasonable restriction.
  700.                           
  701.                         : popupNoMark, popupBlackSymbol and popupInsetFrame can 
  702.                           be combined with others, but combinations of the last 
  703.                           4 are undefined.
  704.  
  705.                 refCon    : if varCode of popupUseAddResMenu, put the 
  706.                           ResType in the refCon field of the control.
  707.  
  708. Spinner            standard use of min, max and value.
  709.                 
  710.                 The control refCon field can be set to a long word 
  711.                 that indicates both the increment to use and a DITL 
  712.                 item to    update (optional).
  713.                 
  714.                 LOWORD = increment value (default increment is 1)
  715.                 HIWORD = DITL item number for an editText item to 
  716.                          update with the control value.
  717.                         
  718. Date & Time        max - if non-zero, reverse 12/24 hour setting.
  719.                 min - if non-zero, draw "3D" control.
  720.                 
  721.                 contrlValue indicates highlighted numbers
  722.                 
  723.                 2    hours
  724.                 3    minutes
  725.                 4    AM/PM
  726.                 7    month  (7,8,9 match user order from Control Panel
  727.                 8    day        and may not have these meanings)
  728.                 9    year
  729.                                     
  730.                 contrlRfCon is seconds as passed to GetDateTime(),  
  731.                 Secs2Date() and Date2Secs() calls.  This is the "value" 
  732.                 that the control adjusts.  Use GetCRefCon() to retrieve 
  733.                 the "date time" value and SetCRefCon() to set it.
  734.                 
  735.                 To "reset" the control (remove hilighted digits & hide
  736.                 arrows), simply set its value to 0 with SetControlValue.
  737.                 
  738.                 To highlight digits, set the control value to one of the
  739.                 values listed above.
  740.                         
  741. HSlider            min = 0, max = 100 - these are set by the control.
  742.  
  743.                 value returned will range from 0 to 100
  744.  
  745. VSlider            refCon is used to indicate 'number of divisions' from 
  746.                 2-20. Default is 7 divisions with tick marks from 0-7.
  747.                 min = 0
  748.                 max = 12*"number of divisions"
  749.                         
  750.                 The value returned will range from 0 to max.
  751.                         
  752.                 The control "thumb" will "snap" to a tick mark.
  753.                 This means that the value will always be 12*tick mark.
  754.  
  755.                 To avoid the "snap" behavior, use varCode 4.
  756.                         
  757. 3D Buttons        standard use of all fields, but with an 
  758.                 additional variation code for "Tog" buttons.
  759.                 
  760. Progress Bar    standard use of all fields.
  761.  
  762.                 Control cannot be disabled.
  763.  
  764. Tab Panel        min        = true height of the control. 
  765.                 max        = number of tabs
  766.                 value    = "active" tab. Title is bold.
  767.                 title    = one per tab, separated by CR (0x0d)
  768.                 refCon    = LoWord = tabs per row (2 - 8) - default of 4
  769.                           HiWord = right margin - no tabs drawn in this area.
  770.                 
  771.                 Rect should be set to #rows * 16 pixels, just enough for 
  772.                 all rows of tabs.
  773.                 
  774.                 Control cannot be disabled.
  775.  
  776. --------------------------------------------------------------------------------
  777.  
  778. Using custom controls in a dialog
  779. =================================
  780.  
  781. To use custom controls in a dialog, it is important to understand the
  782. interaction between the Dialog Manager, Control Manager and resource
  783. definitions for dialogs.
  784.  
  785. Underlying all controls in a Macintosh window (dialog or other) is the Control
  786. Manager.  Fundamental to this is the Toolbox call to create a new control:
  787.  
  788. ControlHandle hCtl;
  789.  
  790. hCtl = NewControl(
  791.             theWindow,        // the window the control belongs to
  792.             *theRect,        // rectangle for control
  793.             title,            // title for control
  794.             visible,        // initially visible or not
  795.             initialValue,    // control value
  796.             min,            // minimum value
  797.             max,            // maximum value
  798.             ctrlType,        // 16*procID+variation code
  799.             refCon            // user specified value
  800.             );
  801.  
  802. ctrlType is an important value and an understanding of its use if key to the
  803. use of custom controls.  The procID is the resource id of a code resource of
  804. type 'CDEF'.  Built into the Macintosh system are 'CDEF' resources of id 0 and
  805. 1 (and others).  The 'CDEF' with procID=0 is used for push buttons, check boxes
  806. and radio buttons - with variation codes of 0, 1 and 2 respectively.
  807.  
  808. So, to create buttons in a window, you could use NewControl and specify:
  809.  
  810.                            = 16*procID+variation code
  811.                            --------------------------
  812. Push Button        : ctrlType = 16*0+0 = 0
  813. Check Box        : ctrlType = 16*0+1 = 1
  814. Radio Button    : ctrlType = 16*0+2 = 2 
  815.  
  816. A special variation code of useWindFont (8) can be used with many controls to
  817. change the font of the control.
  818.  
  819. So, to use a custom control, you simply specify a procID of something other
  820. than 0.  If you want to substitute a custom control (like the 3D Button CDEF)
  821. for the default CDEF id=0, include a CDEF with id=0 in your application's
  822. resource fork.  This was done in the demo program (and in the xDEF.rsrc file).
  823.  
  824. Items in a dialog are specified in resource description files (.r files) using
  825. a syntax unique to your resource compiler.  A dialog resource is composed of a
  826. 'DLOG' resource and a corresponding 'DITL' resource. The 'DLOG' resource
  827. defines the dialog itself, while the 'DITL' resource  defines the item list for
  828. the dialog.  A typical item description in a 'DITL' source file might be:
  829.  
  830. resource 'DITL' (128) {
  831. /*    Control Rect,            ctrlType,     flag,        title            */
  832. /*    ---------------------    -----------    ---------    --------------- */
  833.     {249, 396, 269, 455},    Button         { enabled, "OK"             },
  834.     {249, 324, 269, 383},    Button          { enabled, "Cancel"            },
  835.     {52, 22, 68, 142},        CheckBox     { enabled, "Check box"        },
  836.     {76, 22, 92, 142},        RadioButton { enabled, "Radio button"    }
  837. };
  838.  
  839. For some standard controls (push buttons, radio buttons etc.), there are
  840. special 'DITL' definitions, as shown above.  The Dialog Manager reads the
  841. information in the 'DITL' resource, fills in some default values and calls
  842. NewControl().  (The 'enable' flag is not really a parameter to NewControl(),
  843. but sets the contrlHilite field in the control record.)
  844.  
  845. This means that you don't have to fill in the entire parameter list for
  846. NewControl() to have a control in a dialog - for the standard controls.
  847.  
  848. If you want to use the useWindFont variation code or a custom control in a
  849. dialog, there is some extra work to do…  You must define a special type of
  850. 'DITL' item, "Control" instead of "Button" etc. and then you must provide a
  851. matching resource of type 'CNTL'.  The Dialog Manager will recognize this type
  852. of 'DITL' item and read the 'CNTL' resource to get some of the parameters it
  853. will use in the call to NewControl().
  854.  
  855. The 'CNTL' resource contains fields for all of the parameters needed by
  856. NewControl().  In the example below, the DITL is changed to add the useWindFont
  857. variation to the items shown above, the resource  description would look like:
  858.  
  859. resource 'DITL' (128) {
  860. /*    Control Rect,            ctrlType,     flag,        'CNTL' id        */
  861. /*    ---------------------    -----------    ---------    --------------- */
  862.     {249, 396, 269, 455},    Control         { enabled,        128         },
  863.     {249, 324, 269, 383},    Control     { enabled,        129            },
  864.     {52, 22, 68, 142},        Control     { enabled,        130            },
  865.     {72, 22, 88, 142},        Control        { enabled,        131            }
  866. };
  867.  
  868. /*    Control Rect    initValue    visFlag        max    min    ctrlType    refCon    Title */
  869.  
  870. resource 'CNTL' (128, purgeable) {
  871.     {52, 22, 68, 142},        0,    visible,    1,    0,    16*0+8,        0,        "OK"
  872. };
  873. resource 'CNTL' (130, purgeable) {
  874.     {52, 22, 68, 142},        0,    visible,    1,    0,    16*0+8,        0,        "Cancel"
  875. };
  876. resource 'CNTL' (130, purgeable) {
  877.     {52, 22, 68, 142},        0,    visible,    1,    0,    16*0+1+8,    0,        "Check box"
  878. };
  879. resource 'CNTL' (131, purgeable) {
  880.     {72, 22, 88, 142},        0,    visible,    1,    0,    16*0+2+8,    0,        "Radio button"
  881. };
  882.  
  883. ** IMPORTANT **
  884.  
  885.     There are TWO rectangle definitions here - one in the 'DITL' and 
  886.     one in the 'CNTL'.  If they don't match, your custom control may
  887.     not draw, or it will flicker and seem to move when you first
  888.     show the dialog.  Also, clicks in the DITL rect may not be 
  889.     recognized by the Control when its rect is different. 
  890.     
  891.     Make sure the rects match.
  892.  
  893. If you use a resource editor instead of .r files & a resource compiler, you can
  894. define the 'DITL' and matching 'CNTL' resources directly. Resorcerer does a
  895. fine job at this.  ResEdit is a bit more difficult to use.
  896.  
  897. ResEdit does not keep the 2 rectangles in sync, if you drag a 'DITL' item
  898. around, the corresponding 'CNTL' is not updated.
  899.  
  900. To use ResEdit, open the 'DITL' window and define a new item of type "Control"
  901. from the floating palette.  Double click on the new item and fill in the
  902. resource id and rectangle information.  Move this window aside, but so that you
  903. can still see the rect info.
  904.  
  905. Now, hold down the command+option keys and double click on the item in the
  906. 'DITL' window.  This brings up the 'CNTL' window where you  can fill in the
  907. info for the 'CNTL' resource - fill in the "Bounds Rect" (top, left, bottom,
  908. right) item to match the rect in the 'DITL' window.
  909.  
  910.  
  911. --------------------------------------------------------------------------------
  912. Using custom controls in a normal window
  913. ========================================
  914.  
  915. In some ways, it is easier to use a control in a normal window than in a dialog.
  916. BUT, you have to do mouseDown event processing since the Dialog Manager is not
  917. doing it for you.
  918.  
  919. This is simple and identical to handling scroll bars or buttons in a window.  Just
  920. call FindControl to determine where & if the mouse was clicked in a control, then
  921. call TrackControl.  The code is nothing special, it looks like this:
  922.  
  923.             mousePt = theEvent->where;
  924.             GlobalToLocal(&mousePt);
  925.             partCode = FindControl(mousePt, theDialog, &controlHdl);
  926.             if(partCode && controlHdl) {
  927.                 TrackControl(cHdl, mousePt,  (ProcPtr)myTrack);
  928.             }
  929.             
  930. The only special things about these controls have to do with the last parameter to
  931. TrackControl - the actionProc.  Normally, you can simply take the default
  932. and pass nil as the last parameter.  See demoWind.c for some examples.
  933.  
  934. Exceptions are:
  935.  
  936. Popup Menu
  937. ----------
  938.     You must pass (ProcPtr)-1 to tell the CDEF to "autoTrack".
  939.  
  940. Spinner
  941. -------
  942.     You may define an actionProc which will be called when the mouse is
  943.     clicked in an arrow.  Unlike a scrollBar, the Spinner CDEF will update
  944.     its control value.  So in your action proc, you can call GetCtlValue to
  945.     obtain the current control value and do something with it (like stuff it
  946.     in an edit text record or display it).
  947.     
  948. Sliders
  949. -------
  950.     Sliders don't really need an actionProc, you can call TrackControl with
  951.     a nil actionProc and the slider will work just fine.
  952.     
  953.     If you want to implement a "live" display of the value of a slider control,
  954.     you simply define an actionProc, but use SetCtlAction to tell the control
  955.     to call it as the "thumb" of the slider is being dragged. (You still need
  956.     to call TrackControl though, or the control will not respond to clicks
  957.     in the scale portion of the control).
  958.     
  959.     In your actionProc, you can then call GetCtlValue to obtain the control
  960.     value and display it.
  961.     
  962. For the rest of the CDEFs, simply call TrackControl with a nil action proc 
  963. (unless you want to extract the control value and do something with it each
  964. time the mouse is clicked in the control - then you must define an actionProc).
  965.  
  966. --------------------------------------------------------------------------------
  967. Colorizing Controls & Dialogs
  968. --------------------------------------------------------------------------------
  969.  
  970. The key to having a colored dialog is to include a 'dctb' (or 'actb' for Alerts)
  971. with the same ID as the 'DLOG' or 'ALRT' resource.
  972.  
  973. For controls, there is a similar resource, a 'cctb'.  Either create 'cctb'
  974. resources for each 'CNTL' resource, or to color ALL controls in an application,
  975. create a 'cctb' with ID=0.
  976.  
  977. For the controls that have a "3D" variant, make sure you define the
  978. cTingeLight and cTingeDark colors in your 'cctb' or you won't get a nice
  979. looking control.
  980.  
  981. See demoDialog.r for examples.
  982.  
  983. --------------------------------------------------------------------------------
  984. Changing the font in a Dialog
  985. --------------------------------------------------------------------------------
  986.  
  987. Before showing your dialog (but after creating it), simple calls to:
  988.  
  989.     TextFont(geneva) and
  990.     TextSize(9)
  991.  
  992. will change the dialog font to Geneva 9.  This WILL NOT WORK if you have an
  993. edit text item in the dialog or if you forget to specify the useWindFont
  994. variation for your controls.
  995.  
  996. The best way to change the font for an edit item is to use 'ictb' resources, but
  997. these are a pain.  Only Resorcerer does this well, Rez and ResEdit don't
  998. support 'ictb' resources.
  999.  
  1000. See demoDialog.c for a crude hack that seems to work.
  1001.  
  1002. --------------------------------------------------------------------------------
  1003. Special PopUp menu notes
  1004. --------------------------------------------------------------------------------
  1005.  
  1006. To start, the documentation in Inside Mac VI on the Apple popup menu CDEF
  1007. is wrong in one detail.
  1008.  
  1009. There is no support for "popupRightJust" as shown in figure xxx showing a
  1010. title to the right of the menu.  Instead, titles are always shown to the
  1011. left, but can be left, center or right justified to the left of the menu.
  1012.  
  1013. This justification is done in a "title rect" that extends from the left
  1014. of the control rect for as many pixels as you specify for "title width"
  1015. in the controlMax field of the control template.
  1016.  
  1017. See the "Popup Menus" tab in the demoCDEF program to see how this works.
  1018.  
  1019. A goal in writing this CDEF was to duplicate the Apple CDEF 63, but with
  1020. one that would behave the same under System 6 and System 7 and correctly
  1021. work with colored menus or on a colored background.  The demoCDEF program
  1022. has a dialog that shows both CDEFs side by side.
  1023.  
  1024. I came close to calling this CDEF "yapum" (Yet Another Popup Menu) since
  1025. many have posted similar code.  I never found one that did exactly what
  1026. I wanted (duplicate the behavior of the standard Apple CDEF), so I wrote
  1027. this one.  Thanks to the other writers of popup CDEFs, I learned things
  1028. from your code.
  1029.  
  1030. A major pain in writing this CDEF was insuring that the drawing of the
  1031. popup when "at rest" (which is done by the CDEF) - matched EXACTLY, the
  1032. drawing done by the Menu Manager when the menu is "popped up".  Without
  1033. this, the menu appears jerky as things shift when you click in the control.
  1034. So, a goal in writing this popup CDEF was to duplicate the drawing done
  1035. by the standard MDEF as closely as possible.
  1036.  
  1037. I didn't get the drawing exactly the same in all cases.  Some oddball font
  1038. and size combinations may be off by a pixel or two.  Also, this control has
  1039. a slightly different manner of drawing the "popup symbol" and thus may be
  1040. a bit wider than the Apple CDEF 63 in a few cases.  It does match exactly
  1041. for Chicago 12 fonts.  I also deliberately centered the control title for
  1042. Iconic menus rather than the Apple approach of putting the title along the
  1043. top edge.  IMHO, centered looks better - it is lined up with the menu item
  1044. text.
  1045.  
  1046. As far as I know, you can use this CDEF with exactly the same parameters as
  1047. the Apple CDEF 63 and get the same results.  (I even went as far as pasting
  1048. it into my System and trying out a few apps and CommTools - it worked in
  1049. most cases.)
  1050.  
  1051. I don't recommend doing this though - Standard File was pretty much useless.
  1052. There must be some special hooks in the Apple CDEF for the Folder/Disk/Desktop
  1053. popup in Standard file.
  1054.  
  1055. A minor difference is variation code 2 - this CDEF uses this for a 3D 
  1056. embossed title while the System 6 CDEF uses 2 to mean "use Color QD" and 
  1057. System 7 ignores it.
  1058.  
  1059. I have deliberately NOT implemented 1 "feature".  This CDEF will not draw
  1060. command-keys.  IMHO, popups should not have command key equivalents and
  1061. there is a conflict when drawing - the menu manager will draw the command
  1062. key equivalent where the popup must draw the "popup symbol".  Apple's CDEF
  1063. shifts the command key to left, but then when the menu is popped up, they
  1064. shift to the right.  I find this distracting.
  1065.  
  1066. Two oddities that I have noticed are :
  1067.  
  1068. 1). Because of the AppendDITL calls (I think), menus with icons draw the
  1069. icons before drawing the popup frame.  Apple's CDEF does this too, I suspect
  1070. that it is a GrafPort problem but haven't really investigated.
  1071.  
  1072. 2). If you want an menu with Icons only, no text, you have to supply a space
  1073. as an item string or the standard MDEF ignores the menu.
  1074.  
  1075. Enhancements
  1076. ============
  1077.  
  1078. The popup CDEF in this package has several enhancements to the Apple CDEF.
  1079. These extensions are NOT backward compatible with the Apple CDEF!
  1080.  
  1081. You can see all of these extensions in the demoCDEF program on the 
  1082. "Popup Extensions" tab.
  1083.  
  1084. NOTE: versions earlier than v1.3 of this CDEF used a value of -1 in the
  1085.         contrlMax field to indicate "popupSymbolOnly".  
  1086.         
  1087.         THIS HAS BEEN CHANGED!
  1088.         
  1089. 1). It will handle "dynamic" menus created via NewMenu() as long as you
  1090. call InsertMenu() to add the menu to the menu list.
  1091.  
  1092. 2). Variation code 2 can be used for an embossed title as with the other
  1093. CDEFs in this package.  This is only honored if the window background is
  1094. non-white.
  1095.  
  1096. If the "popupInsetFrame" (below) is also, the menu item text will be
  1097. embossed as well.
  1098.  
  1099. 3). There are several additional variants, all created via "pseudo variation
  1100. codes" which can be combined with the control Max value - which is normally 
  1101. used to specify the width of the title for a popup menu. 
  1102.  
  1103. Header file jimsCDEF.h has definitions for theses extensions.
  1104.  
  1105.     The first 3 are additive and can be combined with any other
  1106.     "pseudo variation code".
  1107.     
  1108.     1. No item marks (popupNoMark)
  1109.     
  1110.         Calling program can use SetItemMark() to set a mark if needed.
  1111.         One use of this would be to create a popup similar to the one
  1112.         used in Standard file dialogs.
  1113.     
  1114.     2. Black symbol (popupBlackSymbol)
  1115.     
  1116.         Default behavior with colored menus is to draw the popup symbol
  1117.         in the item text color. If you always want black symbols, add
  1118.         this "variation code" to controlMax.
  1119.     
  1120.     3. Inset 3D popup (popupInsetFrame)
  1121.     
  1122.         While working on the demoCDEF program, I realized that 3D dialogs
  1123.         (as used in the demo program) and popup menus look somewhat odd
  1124.         together.  The standard, drop-shadowed frame of a popup has the
  1125.         effect of "raising" the popup above the plane of the 3D dialog.
  1126.         
  1127.         So, I added another pseudo variation code to draw the popup menu
  1128.         as an "inset box" - a 3D effect that has the result of placing
  1129.         the popup below the plane of the dialog.  This only works if the
  1130.         dialog background color is non-white.  This effect was lost if the
  1131.         menu background color was white as well, so I chose to use the color
  1132.         of the current grafPort as the background color for the menu (in the
  1133.         case of the demo program, red=green=blue=0xCCCC).
  1134.         
  1135.         Of course, when the menu is "popped", the standard MDEF takes over
  1136.         drawing and the standard menu & drop shadow appear.
  1137.         
  1138.     The following are NOT additive with each other.  If added together,
  1139.     the results are undefined.
  1140.     
  1141.     4. "Symbol" only popups (popupSymbolOnly)
  1142.     
  1143.         For "type in" popups often used for Font size selection in
  1144.         conjunction with edit text items in dialogs. Additional code
  1145.         is needed to implement this, see the demoCDEF program source.
  1146.     
  1147.     5. Popups with no "Symbol" (popupNoSymbol)
  1148.     
  1149.         No downward pointing triangle is drawn, as in the System 6
  1150.         version of CDEF 63.
  1151.     
  1152.     6. Popups with icons only (popupIconOnly)
  1153.     
  1154.         This results in a "popup Icon button" effect since only a
  1155.         framed icon (of any size or type) is drawn.  Item text and
  1156.         the popup symbol are not drawn. 
  1157.         Set the control rect to 5 pixels more than the largest icon.
  1158.     
  1159.     7. Popups with centered text (popupCenterText)
  1160.     
  1161.         This results in a "popup text button" effect since the menu
  1162.         item text is drawn, centered in the control rect.
  1163.  
  1164. --------------------------------------------------------------------------------
  1165. About "TogButtons" 
  1166. --------------------------------------------------------------------------------
  1167. In early November 1991, I ran across an article in the October 1991 "Apple
  1168. Direct" by Bruce Tognazzini - Apple's human interface guru.   Each month Tog
  1169. would write a column dealing with HI issues.  The article that caught my eye
  1170. back then was titled "Case Study: One or more Buttons".  
  1171.  
  1172. I don't think that I can legally include Tog's article with this bit of code,
  1173. but you can find it on many of the Apple Developer CD's in the 
  1174.  
  1175. Periodicals:Apple Direct:Apple Direct Oct '91:Tog folder.  
  1176.  
  1177. It also is in his book "Tog on Interface" as chapter 36.
  1178.  
  1179. To summarize, Tog wrote about the design and usability testing of a new 
  1180. interface element that he called "One or more Buttons" - essentially a control
  1181. that was part Checkbox and part Radio button.  A group of Checkboxes can all be
  1182. "Off" and a group of Radio buttons can only have one "On" value.  What was
  1183. needed was a group that MUST have ONE "On" control but could have many "On"
  1184. controls - a "One or more Button".
  1185.  
  1186. Tog's design for what I call "Tog Buttons" is a cross between a Radio button
  1187. and a Checkbox.  The control is a diamond (a Checkbox rotated 90 degrees) with
  1188. a diamond shaped indicator (like the  circular indicator in a Radio button). 
  1189. The behavior is also a cross between the two other controls.  If only one
  1190. control is ON, then clicking on it turns that control OFF and turns on an
  1191. adjacent control (just like a pair of radio buttons), if one or more of the
  1192. controls is ON, then others can be toggled (just like a checkbox).
  1193.  
  1194. Another twist on the behavior is that if only one control is ON, a click on
  1195. that control will turn if OFF, and turn on the one just above (or to the left
  1196. of) it.  When the first (or last) control  is reached, the direction reverses,
  1197. turning on the one just below  (or to the right).  Tog likened this behavior to
  1198. that of a drop of  mercury when you press on it with a finger (but without the
  1199. toxicity!).
  1200.  
  1201. The behavior is such that with a single ON button, clicking on just that
  1202. button, causes it to "jump" up (or leftward).  If you keep chasing the single
  1203. ON button, it will keep "jumping" up until it must reverse direction and start
  1204. "jumping" down.  Unless you are "chasing" a button like this, when only one
  1205. button is ON, the default behavior is to jump UP (or to the left).  To see
  1206. this, try the cdefDemo program and you will see what I mean.   
  1207.  
  1208. For some reason, this appealed to me as an interesting project and I spent a
  1209. fun afternoon implementing Tog's idea.  I ended up creating a CDEF to implement
  1210. the control described by Tog and a couple of routines in C to support the
  1211. desired behavior of "Tog Buttons".
  1212.  
  1213. --------------------------------------------------------------------------------
  1214. How to use a Tog Button in a dialog
  1215. ===================================
  1216.  
  1217. Obviously, using a Tog Button is only needed if you have a situation that has a
  1218. group of items that requires "One or Many" values.  An example might be a
  1219. search :
  1220.  
  1221.    - Search -----------------
  1222.   |                          |
  1223.   | <•> C files (.c)         |
  1224.   | < > Include files (.h)   |
  1225.   | < > Resource files (.r)  |
  1226.   |                          |
  1227.    --------------------------
  1228.    
  1229. The file cdefDemo.c shows how to use "Tog Buttons", but here is a brief list.
  1230.  
  1231. 1. Include the files TogLib.c/TogLib.h in your project.
  1232.  
  1233. 2. Define the group of "Tog Buttons" in your dialog resource.
  1234.  
  1235. 3. DITL item numbers MUST be successively numbered for each group of "Tog
  1236.    Buttons".  This is IMPORTANT!
  1237.  
  1238. 4. After calling GetNewDialog, but before calling ModalDialog,  call
  1239.    initTogButtons() for each group of "Tog Buttons".
  1240.  
  1241. 5. When a "Tog Button" is clicked, call setTogButtons() for that group of "Tog
  1242.    Buttons".
  1243.  
  1244. 6. When a non-Tog Button control is clicked, do whatever is needed, then call
  1245.    resetTogButtons() for each group of  "Tog Buttons".  This step simply insures
  1246.    that the next click on a "Tog Button" will "go up".
  1247.  
  1248. 7. Use regular calls to GetDItem() and GetCtlValue() to retrieve the control
  1249.    values for "Tog Buttons".
  1250.  
  1251. The TogLib routines are the key to maintaining consistent behavior of the "Tog
  1252. Buttons".  TogLib.h has a short description of each routine.
  1253.  
  1254. --------------------------------------------------------------------------------
  1255. About Tab Panels
  1256. --------------------------------------------------------------------------------
  1257. Tab panels are what I call dialogs that use the TabPanel CDEF in this package.
  1258.  
  1259. The CDEF is modeled after what I think is Microsoft's "Tabbed dialog" interface
  1260. design.  I think that this is being used in the new Mac versions of Word &
  1261. Excel, but I haven't seen them yet.
  1262.  
  1263. It could be used as an alternative to the common Mac approach of multi-panel
  1264. dialogs that use a list of Icons to switch among several panels.
  1265.  
  1266. This is doubtless a controversial interface element - even more so on the Mac. 
  1267. I don't condone it's use, I simply wanted to see if I could write a control
  1268. like this.
  1269.  
  1270. Think long and hard before you use this on the Mac - it may be rather foreign
  1271. to Mac users and will take some thought.  One of the biggest difficulties is
  1272. "Where do the OK & Cancel buttons go?" and "What does a click on a tab mean?" -
  1273. should changes be applied immediately, or wait for an OK on the dialog?
  1274.  
  1275. If OK & Cancel are inside the "Tab" control, do you have to click on OK before
  1276. changing tabs?  How do you exit the dialog?  Do you then need a "Done" button".
  1277. Is a click on a tab the same as OK? and so on…
  1278.  
  1279. If the OK and Cancel buttons are outside the "Tab" control, then do you need an
  1280. "Apply" button that must be clicked  or you loose changes if you switch panels
  1281. by clicking on a  new tab?  Or is a click on a tab is that an implied
  1282. acceptance of changes that will take effect when you click "OK"?
  1283.  
  1284. There is some subtle but important stuff here. Think about it!
  1285.  
  1286. Using the Tab Panel CDEF
  1287. ------------------------
  1288.  
  1289. You can specify from 1 to 40 tabs with this control (one would be silly and
  1290. 40 is overkill).  Tabs are presented with 4 per row by default, each tab is 
  1291. 1/4 of the width of the control.  "Tabs per row" may be between 2 and 8.
  1292.  
  1293. If you specify a tab count that is not a multiple of "tabs per row", the 
  1294. remaining tabs  will be wider than the others so that the entire control width 
  1295. is occupied.  This looked better (IMHO) than having an empty space or a "dead"
  1296. tab.
  1297.  
  1298. The control max value indicates the total number of tabs. 
  1299.  
  1300. The control title should contain a title for each tab, separated by a CR.  
  1301.  
  1302. If you want to change the default number of tabs per row, put a value
  1303. from 2 to 8 in the LoWord of the refCon field.
  1304.  
  1305. If you want a "notch" on the right side with no tabs, put a "notch" value 
  1306. in the HiWord of the refCon field.  
  1307.  
  1308. The control rect height should be set to #rows * height of 1 tab.  Then set 
  1309. the REAL height for the entire panel in the contrlMin field of the control
  1310. template.  
  1311.  
  1312. ** NOTE ** Be particularly careful to match up the DITL item rect and CNTL
  1313. rects - if these are not the same, you may end up with a "dead" row of tabs
  1314. that will not respond to a click.
  1315.  
  1316. The height of each row of tabs is calculated as : controlHeight/rows. 16 pixels
  1317. per row is a good size.  So, if you need 2 rows of tabs, set the control rect 
  1318. to be 32 high.
  1319.  
  1320. By default, this control will use a Geneva 9 font, with the "active" tab drawn
  1321. as Bold.  If you use the useWindFont variation code of 8, it will use the current
  1322. font. A variation code of 1 will use the System font at all times, underlined 
  1323. instead of bold (IMHO, this looks better than bold Chicago 12).
  1324.  
  1325. A variation code of 2 will force a single row of tabs, with as many tabs as 
  1326. specified by controlMax, each as wide as controlWidth/# tabs.
  1327.     
  1328. If the background is not white, the control will draw as a "3D" control.
  1329.     
  1330. Please note that the control cannot be disabled, nor can a single tab be disabled.
  1331.  
  1332. If you have a situation where an entire panel should be disabled, disable each
  1333. of the controls on the panel.
  1334.  
  1335. Changing the controls as you switch from tab to tab can be done in several ways.
  1336. One is to use the AppendDITL and ShortenDITL found in System 7 - this is the 
  1337. approach used in the demoCDEF program and in support routines found in
  1338. panelAssist.c. That file has 3 routines that might be handy - one to swap panels,
  1339. one to implement command+number keys as an alternative to clicking on a tab and
  1340. another to implement command+Tab or control+Tab to cycle through the tabs.
  1341.  
  1342. If you need to use the TabPanel CDEF with System 6, a series of MoveControl or 
  1343. Hide/ShowControl calls would probably do the trick.
  1344.  
  1345. The files demoDialog.c and tabDemo.c show how to use a "Tab Panel".
  1346.  
  1347. File demoDialog.c has routines that preserve the settings of each 
  1348. control on each panel.
  1349.  
  1350. File tabDemo.c is a "bare bones" example of how to work with the CDEF.
  1351.  
  1352. Briefly, to use the TabPanel CDEF:
  1353.  
  1354. 1. Include the files panelAssist.c/panelAssist.h in your project.
  1355.  
  1356. 2. Define a DLOG resource and DITL that contains just 3 controls "OK",
  1357.    "Cancel" and the TabPanel control as items 1-3.  
  1358.  
  1359. 3. Set the contrlMax value to the number of tabs you want and provide
  1360.    a title for each in the control title.
  1361.    
  1362. 4. Define a 'DITL' resource for each tab.  Number them successively,
  1363.    starting with the previous DITL+1.
  1364.  
  1365. 5. Study the code in demoDialog.c.  That example places the OK & Cancel buttons
  1366.    outside the panel and saves all control values to a temp area before switching
  1367.    to another panel.
  1368.  
  1369. 6. When Modal dialog informs your program that a Tab was clicked (itemHit is
  1370. equal to the tabPanel DITL item), do the following:
  1371.     
  1372.         - get the value of the tab control.
  1373.         - save the values of other controls on the current panel.
  1374.         - call panelSwap with the new tab value to change panels.
  1375.             (this uses CountDITL, ShortenDITL and AppendDITL)
  1376.         - restore the values of the controls on the new panel.
  1377.         
  1378. 7. If you want to use command+number keys to switch panels, call panelCmdKey()
  1379. from your dialog filter routine whenever a keyboard event occurs with the
  1380. command key down - obviously, this is only good for 10 or fewer tabs.  
  1381.  
  1382. To use command+Tab or control+Tab to rotate through tab panels, call 
  1383. panelCmdTab() when the control or command keys are pressed.
  1384.  
  1385.